<script setup lang="ts">
import { onBeforeUnmount, ref, useAttrs, watch } from 'vue'
import type { PropType } from 'vue'
import type { UploadChangeParam, UploadProps } from 'ant-design-vue'
import { QuestionCircleOutlined } from '@ant-design/icons-vue'
import type { FormInstance, FormOptions } from './types/type'
// import E from 'wangeditor'

const props = defineProps({
  options: {
    type: Array as PropType<FormOptions[]>,
    default: () => [],
    require: true,
  },
})

// const edit = ref()
const model = ref<any>({})
const rules = ref<any>({})
const form = ref<FormInstance | null>()
const fileList = ref<UploadProps['fileList']>([])

const attrs: any = useAttrs()

_initForm()

watch(() => props.options, () => {
  _initForm()
}, { deep: true })

// 根据option构造model和rules
function _initForm() {
  const m: any = {}
  const r: any = {}
  // 初始化富文本编辑器
  props.options.forEach((item: any) => {
    m[item.prop!] = item.value
    r[item.prop!] = item.rules
    // if (item.type === 'editor') {
    //   // 初始化富文本
    //   nextTick(() => {
    //     if (document.getElementById('editor')) {
    //       const editor = new E('#editor')
    //       editor.config.placeholder = item.placeholder!
    //       editor.create()
    //       // 初始化富文本的内容
    //       editor.txt.html(item.value)
    //       editor.config.onchange = (newHtml: string) => {
    //         model.value[item.prop!] = newHtml
    //       }
    //       edit.value = editor
    //     }
    //   })
    // }
  })

  model.value = m
  rules.value = r
}

function validate() {
  return form.value!.validate
}

function resetFields() {
  form.value!.resetFields()
  fileList.value = []
  // 重置富文本编辑器的内容
  // 获取到富文本的配置项
  // if (props.options && props.options.length) {
  //   const editorItem = props.options.find(item => item.type === 'editor')!
  //   edit.value?.txt.html(editorItem.value)
  // }
}

defineExpose({
  validate,
  resetFields,
  model,
})

function onChange({ fileList: files }: UploadChangeParam) {
  fileList.value = files.map((item: any) => {
    const url = item.name
    return {
      uid: item.uid,
      name: item.name,
      status: 'done',
      url,
    }
  })
}

// 监听fileList变化
const stopWatch = watch(() => fileList, () => {
  updateModelValue()
}, {
  deep: true,
})

function updateModelValue() {
  const urls: string[] = []
  fileList.value!.forEach((file: any) => {
    if (file.status === 'done' && file.url)
      urls.push(file.url)
  })
  const uploadItem = props.options.find(item => item.type === 'upload')
  if (uploadItem)
    model.value[uploadItem.prop!] = urls
}

onBeforeUnmount(() => stopWatch())
</script>

<template>
  <a-form ref="form" v-bind="$attrs" :model="model" :rules="rules">
    <template v-for="(item) in options" :key="item.id || item .prop">
      <!-- 渲染特殊类型 -->
      <template v-if="item.type === 'table'">
        <a-form-item :label="item.label" :name="item.prop">
          <slot name="tableAction" :data="item" />
        </a-form-item>
      </template>
      <template v-else>
        <!-- 组件里有子组件 -->
        <a-form-item v-if="item.children && item.children.length" :name="item.prop">
          <template v-if="item.label" #label>
            {{ item.label }}
            <a-tooltip v-if="item.tooltip">
              <template #title>
                {{ item.tooltip }}
              </template>
              <QuestionCircleOutlined style="margin-left: 8px;" />
            </a-tooltip>
          </template>
          <component v-bind="item.attrs" :is="`a-${item.type}`" v-model:value="model[item.prop!]" :placeholder="item.placeholder" :size="item.size">
            <component
              v-bind="child.attrs"
              :is="`a-${child.type}`"
              v-for="(child, idx) in item.children"
              :key="idx"
              :label="child.label"
              :value="child.value"
              :disabled="child.disabled!"
            >
              {{ child.label }}
            </component>
          </component>
        </a-form-item>
        <!-- 无子组件 -->
        <a-form-item v-else :name="item.prop">
          <template v-if="item.label" #label>
            {{ item.label }}
            <a-tooltip v-if="item.tooltip">
              <template #title>
                {{ item.tooltip }}
              </template>
              <QuestionCircleOutlined style="margin-left: 8px;" />
            </a-tooltip>
          </template>
          <component
            v-bind="item.attrs"
            :is="`a-${item.type}`"
            v-if="item.type !== 'switch' && item.type !== 'upload' && item.type !== 'editor'"
            v-model:value="model[item.prop!]"
            :placeholder="item.placeholder"
            :size="item.size"
          >
            <!-- 处理input组件添加插槽的情况 -->
            <template v-if="item.attrs?.slot" #[item.attrs?.slot]>
              <component :is="item.attrs?.icon" :style="item.attrs?.styleIcon" />
            </template>
          </component>
          <a-switch v-if="item.type === 'switch'" v-model:checked="model[item.prop!]" />
          <a-upload
            v-if="item.type === 'upload'"
            v-model:file-list="fileList"
            v-bind="item.uploadAttrs"
            :on-change="onChange"
          >
            <slot name="uploadArea" />
            <slot name="uploadTip" />
          </a-upload>
        <!-- <div v-if="item.type === 'editor'" id="editor" /> -->
        </a-form-item>
      </template>
    </template>
    <a-form-item v-if="attrs.showfooter" :wrapper-col="{ span: attrs.wrapperCol?.span, offset: attrs.labelCol?.span }">
      <slot name="footerAction" />
    </a-form-item>
  </a-form>
</template>
